package cn.mw.cmdb.util;

import cn.mw.cmdb.entity.InstanceGroupByPathAndStatus;
import cn.mw.cmdb.entity.InstanceGroupBySingleAndStatus;
import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.entity.InstanceInfoExtend;
import cn.mw.cmdb.enums.ZabbixAssetsStatusEnum;
import cn.mw.cmdb.param.AssetsScanParam;
import cn.mw.cmdb.view.TreeViewObject;
import cn.mw.microMonitorCommon.api.cmdb.AssetCatolog;
import cn.mw.microMonitorCommon.api.cmdb.AssetInfo;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.api.scan.RuleParam;
import cn.mw.microMonitorCommon.enums.RuleType;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

public class AssetsTool {
    public static AssetInfo convertFrom(InstanceInfo instanceInfo){
        AssetInfo assetInfo = new AssetInfo();
        assetInfo.setId(instanceInfo.getId());
        assetInfo.setInstanceName(instanceInfo.getInstanceName());
        assetInfo.setMonitoringServerType(instanceInfo.getMonitorType());
        assetInfo.setMonitorServerId(instanceInfo.getMonitorServerId());
        assetInfo.setTypeId(instanceInfo.getMonitorTypeId());
        return assetInfo;
    }

    public static AssetCatolog convertFrom(TreeView treeView){
        AssetCatolog assetCatolog = new AssetCatolog();
        assetCatolog.setId(treeView.getId().toString());
        String parentId = (null == treeView.getParentId()?"":treeView.getParentId().toString());
        assetCatolog.setParentId(parentId);
        assetCatolog.setName(treeView.getItemName());
        assetCatolog.setType(treeView.getType());
        TreeViewObject treeViewObject = (TreeViewObject)treeView;
        if(null != treeViewObject && null != treeViewObject.getChilds()){
            for(TreeView child: treeViewObject.getChilds()){
                if(null != child){
                    AssetCatolog sub = convertFrom(child);
                    assetCatolog.addAssetCatolog(sub);
                }
            }
        }
        return assetCatolog;
    }

    //单个资产扫描时,前端接口传参与批量扫描时不一致
    //需要进行转换
    public static void convertSingleScanParam(AssetsScanParam param){
        List<RuleParam> ruleParams = new ArrayList<>();
        RuleParam ruleParam = null;
        RuleType type = RuleType.getInfoByName(param.getMw_ruleType());
        switch (type){
            case Agent:
                ruleParam = new RuleParam(param.getMw_ruleType() ,param.getMw_port());
                break;
            case SNMPv1:
            case SNMPv2:
                ruleParam = new RuleParam(param.getMw_ruleType() ,param.getMw_port() ,param.getMw_community());
                break;
            case SNMPv3:
                ruleParam = new RuleParam(param.getMw_ruleType(), param.getMw_contextName(), param.getMw_securityName()
                        , param.getMw_securityLevel(), param.getMw_authAlgName(), param.getMw_authValue()
                        , param.getMw_privAlgName(), param.getMw_priValue());
        }
        ruleParams.add(ruleParam);
        param.setRuleParams(ruleParams);
        param.setIps(param.getMw_inBandIp());

    }

    public static String calcItemAssetsStatus(List<InstanceInfoExtend> instanceInfoList, TreeView treeView) {
        if (CollectionUtils.isNotEmpty(instanceInfoList)) {
            List<String> childStatus = instanceInfoList.stream().map(item -> item.getItemAssetsStatus() == null ? ZabbixAssetsStatusEnum.UNKNOWN.getName() : item.getItemAssetsStatus()).toList();
            treeView.setChildStatus(childStatus);
            if (childStatus.stream().distinct().toList().size() == 1) {
                return childStatus.get(0);
            }
            return ZabbixAssetsStatusEnum.ABNORMAL.getName();
        }
        return null;
    }

    public static String calcItemAssetsStatusContext(List<ItemAssetsStatusContext> contexts, TreeView treeView) {
        if (CollectionUtils.isNotEmpty(contexts)) {
            List<String> childStatus = new ArrayList<>();
            for(ItemAssetsStatusContext context: contexts){
                if(!StringUtils.hasText(context.getStatus())){
                    context.setStatus(ZabbixAssetsStatusEnum.UNKNOWN.getName());
                }

                childStatus.addAll(Collections.nCopies(context.getCount() ,context.getStatus()));
            }
            treeView.setChildStatus(childStatus);
            if (contexts.size() == 1) {
                return contexts.get(0).getStatus();
            }
            return ZabbixAssetsStatusEnum.ABNORMAL.getName();
        }
        return null;
    }

    public static Map<String, List<ItemAssetsStatusContext>> initModelAndGroupIdSet(Set<String> modelIds , Set<String> groupIds , List<InstanceGroupByPathAndStatus> statusList){
        Map<String, List<ItemAssetsStatusContext>> idContextMap = new HashMap<>();
        for(InstanceGroupByPathAndStatus item: statusList){
            List<String> path = item.getPath();
            int pathSize = path.size();
            int lastIndex = pathSize - 1;
            for(int i=0;i<pathSize;i++){
                String id = path.get(i);
                if(i == lastIndex){
                    modelIds.add(id);
                }else{
                    groupIds.add(id);
                }

                List<ItemAssetsStatusContext> contexts = idContextMap.get(id);
                if(null == contexts){
                    contexts = new ArrayList<>();
                    idContextMap.put(id ,contexts);
                }
                contexts.add(new ItemAssetsStatusContext(item.getItemAssetsStatus() ,item.getCount()));
            }
        }
        return idContextMap;
    }

    public static Map<String, List<ItemAssetsStatusContext>> initGroupIdSet(Set<String> idSet ,List<InstanceGroupBySingleAndStatus> statusList){
        Map<String, List<ItemAssetsStatusContext>> idContextMap = new HashMap<>();
        for(InstanceGroupBySingleAndStatus item: statusList){
            String id = item.getDataId();
            idSet.add(id);
            List<ItemAssetsStatusContext> contexts = idContextMap.get(id);
            if(null == contexts){
                contexts = new ArrayList<>();
                idContextMap.put(id ,contexts);
            }
            contexts.add(new ItemAssetsStatusContext(item.getItemAssetsStatus() ,item.getCount()));
        }

        return idContextMap;
    }

    public static int calcItemAssetsStatusCount(List<ItemAssetsStatusContext> contexts){
        int count = 0;
        for(ItemAssetsStatusContext context: contexts){
            count += context.getCount();
        }
        return count;
    }

    public static class ItemAssetsStatusContext{
        private String status;
        private int count;

        public ItemAssetsStatusContext(String status, int count){
            this.status = status;
            this.count = count;
        }

        public String getStatus() {
            return status;
        }

        public int getCount() {
            return count;
        }

        public void setStatus(String status) {
            this.status = status;
        }
    }
}
